﻿using System;
using System.Collections.Generic;
using Mono.Cecil;
using TK_CSLua.ILAnalyze;

namespace CSLua
{
	// Token: 0x02000024 RID: 36
	public class LuaTypeGenerator : TypeGenerator
	{
		// Token: 0x0600015E RID: 350 RVA: 0x00008E2F File Offset: 0x0000702F
		public LuaTypeGenerator(LuaType luaType, CodeWriter builder) : base(luaType, builder)
		{
		}

		// Token: 0x0600015F RID: 351 RVA: 0x000096A5 File Offset: 0x000078A5
		protected override string Export(string typeDefineName)
		{
			return "return " + typeDefineName;
		}

		// Token: 0x06000160 RID: 352 RVA: 0x000096B2 File Offset: 0x000078B2
		protected override string FileSuffix()
		{
			return ".lua";
		}

		// Token: 0x06000161 RID: 353 RVA: 0x000096BC File Offset: 0x000078BC
		protected override void generateClassDefine(LuaType clazz, bool defined = false)
		{
			TypeDefinition type = clazz.ILTypeDef;
			string typeDefName = this.buildContext.getTypeDefineName(type);
			string typeFullName = BuilderUtils.GetTypeFullname(type, true);
			string prefix = "";
			string baseType = "";
			if (!defined)
			{
				prefix = "local ";
			}
			if (base.isNeedExtends(type))
			{
				baseType = "," + this.buildContext.getTypeId(type.BaseType, false);
			}
			this.writer.codeFormat("{0}{1} = class('{2}'{3})\n", new object[]
			{
				prefix,
				typeDefName,
				typeFullName,
				baseType
			}).nextLine();
		}

		// Token: 0x06000162 RID: 354 RVA: 0x00009750 File Offset: 0x00007950
		public override string buildHeaderCode()
		{
			this.writer.push();
			this.writer.commentLine("-----------");
			this.writer.commentLine("-缓存类型和静态绑定的变量");
			Dictionary<string, string> cache_types = new Dictionary<string, string>();
			Dictionary<string, string> cache_methods = new Dictionary<string, string>();
			foreach (KeyValuePair<TypeReference, string> pa in this.buildContext.reftypes)
			{
				cache_types[this.buildContext.getNativeTypeName(pa.Key)] = pa.Value;
			}
			foreach (KeyValuePair<MethodReference, string> pa2 in this.buildContext.refmethods)
			{
				cache_methods[this.buildContext.reftypes[pa2.Key.DeclaringType] + "." + this.buildContext.getMethodName(pa2.Key)] = pa2.Value;
			}
			foreach (KeyValuePair<string, string> pa3 in cache_types)
			{
				this.writer.defineLocalValue(pa3.Value, pa3.Key);
			}
			foreach (KeyValuePair<string, string> pa4 in cache_methods)
			{
				this.writer.defineLocalValue(pa4.Value, pa4.Key);
			}
			this.writer.commentLine("-----------");
			this.writer.commentLine("-本类型里被引用函数的声明");
			foreach (string method in this.buildContext.cachedSelfMethods)
			{
				this.writer.defineLocalValue(method, null);
			}
			this.writer.commentLine("-----------");
			this.writer.commentLine("------");
			this.writer.commentLine("-code begin");
			return this.writer.pop();
		}

		// Token: 0x06000163 RID: 355 RVA: 0x000099D8 File Offset: 0x00007BD8
		protected override void generateCtorFieldInit(TypeDefinition type)
		{
			foreach (FieldDefinition field in type.Fields)
			{
				if (!field.IsStatic && !field.HasDefault)
				{
					this.writer.codeFormat("{0}.{1} = {2}", new object[]
					{
						this.writer.tokens.self,
						field.luaIdentifier(),
						this.buildContext.defaultValueCode(field.FieldType)
					}).nextLine();
				}
			}
		}

		// Token: 0x06000164 RID: 356 RVA: 0x00009A80 File Offset: 0x00007C80
		protected override MethodGenerator CreateMethodGenerator(LuaMethod luaMethod)
		{
			return new LuaMethodGenerator(this, luaMethod);
		}

		// Token: 0x06000165 RID: 357 RVA: 0x00009A8C File Offset: 0x00007C8C
		protected override void GenerateCtor(LuaType luaType)
		{
			TypeDefinition type = luaType.ILTypeDef;
			this.writer.beginDefineMethod(this.buildContext.getTypeDefineName(type), false, this.writer.tokens.ctorName, delegate
			{
				this.writer.code("...");
			}).shiftRightNewLine();
			if (base.isNeedExtends(type))
			{
				this.writer.codeFormat("{0}.{1}(self,...)", new object[]
				{
					this.buildContext.getTypeId(type.BaseType, false),
					this.writer.tokens.ctorName
				}).nextLine();
			}
			this.generateCtorFieldInit(type);
			this.writer.shiftLeftNewLine(delegate()
			{
				this.writer.endDefineMethod();
			});
		}

		// Token: 0x06000166 RID: 358 RVA: 0x00009B48 File Offset: 0x00007D48
		protected override string generateStaticInit()
		{
			this.writer.push();
			foreach (LuaType clazz in this.luaType.StaticInitTypes)
			{
				this.writer.code(this.buildContext.getTypeDefineName(clazz.ILTypeDef) + "." + BuildConfig.static_initialize_func + "()").nextLine();
			}
			return this.writer.pop();
		}

		// Token: 0x06000167 RID: 359 RVA: 0x00009BE0 File Offset: 0x00007DE0
		protected override void generateAssignNestdClass(LuaType clazz)
		{
			this.writer.splitList<LuaType>(clazz.NestedPath, ".", delegate(LuaType item, int i)
			{
				this.writer.code(item.ILTypeDef.luaIdentifier());
			});
			this.writer.code(".").code(clazz.ILTypeDef.luaIdentifier()).code(" = ").code(this.buildContext.getTypeDefineName(clazz.ILTypeDef)).nextLine();
		}

		// Token: 0x06000168 RID: 360 RVA: 0x00009C58 File Offset: 0x00007E58
		protected override bool tryGenerateModelClone(LuaType luaType)
		{
			TypeDefinition type = luaType.ILTypeDef;
			if (type.hasAttributes(BuildConfig.cloneAttribute))
			{
				this.writer.codeFormat("function {0}:_csl_copy_fields(src)", new object[]
				{
					this.buildContext.getTypeDefineName(type)
				}).shiftRightNewLine();
				if (type.BaseType != null && type.BaseType.Resolve().hasAttributes(BuildConfig.cloneAttribute))
				{
					this.writer.codeFormat("{0}._csl_copy_fields(self,src)", new object[]
					{
						this.buildContext.getTypeId(type.BaseType, false)
					}).nextLine();
				}
				foreach (FieldDefinition field in type.Fields)
				{
					field.FieldType.Resolve();
					this.writer.codeFormat("self.{0}={1}(src.{0},self.{0})", new object[]
					{
						field.luaIdentifier(),
						this.buildContext.getCSLLibs(CSLLibs.CSLCloneObj)
					}).nextLine();
				}
				this.writer.shiftLeftNewLine("end");
				return true;
			}
			return false;
		}

		// Token: 0x06000169 RID: 361 RVA: 0x00009D90 File Offset: 0x00007F90
		protected override bool tryGenerateBehaviourBind()
		{
			if (this.luaType.BindFields != null)
			{
				this.writer.code("def_bind(" + this.buildContext.getTypeDefineName(this.mainTypeDef) + ",{").shiftRightNewLine();
				foreach (BindItem field in this.luaType.BindFields)
				{
					string bindName = "";
					if (field.targetName != null)
					{
						bindName = ",name='" + field.targetName + "'";
					}
					string typeName;
					if (field.luaType)
					{
						typeName = "'" + field.field.FieldType.luaIdentifier() + "'";
					}
					else
					{
						string typeRef = this.buildContext.getTypeId(field.field.FieldType, false);
						typeName = "typeof(" + typeRef + ")";
					}
					if (field.noteText != null && field.noteText.Length > 0 && field.headText != null && field.headText.Length > 0)
					{
						this.writer.code("{").codeFormat("'{0}',{1}{2},noteText='{3}',headText='{4}'", new object[]
						{
							field.field.luaIdentifier(),
							typeName,
							bindName,
							field.noteText,
							field.headText
						}).code("},").nextLine();
					}
					else if (field.noteText != null && field.noteText.Length > 0)
					{
						this.writer.code("{").codeFormat("'{0}',{1}{2},noteText='{3}'", new object[]
						{
							field.field.luaIdentifier(),
							typeName,
							bindName,
							field.noteText
						}).code("},").nextLine();
					}
					else
					{
						this.writer.code("{").codeFormat("'{0}',{1}{2}", new object[]
						{
							field.field.luaIdentifier(),
							typeName,
							bindName
						}).code("},").nextLine();
					}
				}
				this.writer.shiftLeftNewLine("})");
				return true;
			}
			return false;
		}
	}
}
